/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.javanile.uxml;

/**
 *
 * @author cicciodarkast
 */
public class uXmlParser {
	private class Const {
		public final static int BEGIN		= 0;
		public final static int TAG			= 1;
		public final static int TAG_OPEN	= 11;
		public final static int ATTR		= 2;
		public final static int CONTENT		= 5;
		public final static int TAG_HOPE	= 12;
		public final static int TAG_CLOSE	= 18;
		public final static int CALL		= 3;
		public final static int EXIT		= 9;
	}
	public static uXmlDocument parse(String xml) {
		uXmlDocument doc = new uXmlDocument();

		doc.set(xml);

		int c = 0;
		
		if (xml.startsWith("<?xml")) {c = xml.indexOf("?>")+2;}

		while(c<xml.length()) {
			uXmlNode n = parseNode(doc,xml,c);
			doc.add(n);
			c = n.end();
		}

		return doc;
	}
	private static uXmlNode parseNode(uXmlDocument d,String i, int offset) {
		//System.out.println("PN:"+offset);
		int	 o = Const.BEGIN;
		uXmlNode n = new uXmlNode();
		//int[] n = new int[20];
		int  c = offset;
		while(c<i.length()) {
			char s = i.charAt(c);
            //System.out.println("S:"+o+" "+"("+(s+")").trim());
			switch(o) {
				case Const.BEGIN:switch(s) {
					case '<':o=Const.TAG;break;
					}break;

				case Const.CONTENT:switch(s) {
					case '<':o=Const.TAG_HOPE;break;
					}break;

				case Const.TAG:switch(s) {
					case '/':o=Const.TAG_CLOSE;	n.cont_close(c-1);	break;
					default :o=Const.TAG_OPEN;	n.node_open(c-1);	break;
					}break;

				case Const.TAG_CLOSE:switch(s) {
					case '>':o=Const.EXIT;		n.node_close(c);	break;
					}break;

				case Const.TAG_OPEN:switch(s) {
					case ' ':o=Const.ATTR;		n.attr_open(c);		break;
					case '>':o=Const.CONTENT;	n.cont_open(c);		break;
					}break;
				
				case Const.TAG_HOPE:switch(s) {
					case '/':o=Const.TAG_CLOSE;	n.cont_close(c-1);	break;
					default :o=Const.CALL;break;
					}break;

				case Const.ATTR:switch(s) {
					case '>':o=Const.CONTENT;	n.cont_open(c);		break;
					}break;
			}
            c++;
			switch(o) {
				case Const.CALL:
					uXmlNode y = parseNode(d, i, c-2);
					d.add(y);
					c=y.end();
					o = Const.CONTENT;
					break;
				case Const.EXIT:return n;
			}
		}
		return n;
	}
}
